﻿using System;
using System.Collections.Generic;
using System.Text;
using PostSharp.Aspects.Dependencies;

namespace Arcana.Contract.Method.Returns
{
    /// <summary>
    /// Represents a contract that adheres to <b>Method returns an enumerable collection which has the specified item.</b>
    /// </summary>
    /// <remarks>
    /// The method return value should have a return type that is an instance of
    /// <see cref="System.Collections.IEnumerable"/> other wise an instance of
    /// <see cref="System.ArgumentException"/> is throws in run-time.
    /// </remarks>
    [Serializable]
    [ProvideAspectRole(Roles.Contract)]
    [ProvideAspectRole(Roles.Method)]
    [ProvideAspectRole(Roles.ReturnValue)]
    [ProvideAspectRole(Roles.Conditional)]
    [AspectRoleDependency(AspectDependencyAction.Commute, Roles.Conditional)]
    public sealed class HasAttribute : ComparingContractBase
    {
        private object _value;

        /// <summary>
        /// Initializes a new instance of <b>Method.Returns.HasAttribute</b>.
        /// </summary>
        /// <remarks>
        /// The method return value should have a return type that is an instance of
        /// <see cref="System.Collections.IEnumerable"/> other wise an instance of
        /// <see cref="System.ArgumentException"/> is throws in run-time.
        /// </remarks>
        /// <param name="value">The value which the method return value as an enumerable collection should have.</param>
        public HasAttribute(object value)
        {
            _value = value;
        }

        /// <summary>
        /// Performs validation on the return value.
        /// </summary>
        /// <remarks>
        /// The method return value should have a return type that is an instance of
        /// <see cref="System.Collections.IEnumerable"/> other wise an instance of
        /// <see cref="System.ArgumentException"/> is throws in run-time.
        /// </remarks>
        /// <param name="value">The return value that should be validated.</param>
        /// <returns><b>true</b> if <i>value</i> is validated, otherwise <b>false</b>.</returns>
        protected override bool ValidateValue(object value)
        {
            var _value = value as System.Collections.IEnumerable;
            if (_value == null) throw new ArgumentException();
            foreach (var collectionItem in _value)
            {
                if (Comparer.Compare(collectionItem, this._value) == 0) return true;
            }
            return false;
        }
    }
}
